/*
 * TraceDebug.c
 *
 *  Created on: 2012/08/03
 *      Author: guanxiaoying
 */
#include "../tracedef.h"
#include "../../table/core_table.h"
#include "trace_cmd.h"
PSZ  Tr_DbGetLocation( AST astLoc ){
	static CHAR buffer[(OS_FULLPATH+20)*4]="";
	static U4 offset = 0;
	U4 begin;
	U4 len;
	if( offset < (OS_FULLPATH+20)*3 ){
		begin = offset+1;
	}else{
		begin = 0;
	}
	buffer[begin]='\0';
	len = CCodeScope.getFilePath( astLoc, &buffer[begin], OS_FULLPATH );
	sprintf( &buffer[begin+len], ":%ld.%d~%ld.%d", CCodeScope.getBeginLine(astLoc),
			CCodeScope.getBeginLineOffset(astLoc),
			CCodeScope.getEndLine( astLoc ),
			CCodeScope.getEndLineOffset( astLoc ));
	offset = begin + strlen( &buffer[begin] );
	return &buffer[begin];
}
PSZ  Tr_DbGetCommandName( AST astCmd ){
	PSZ str;
	U4 kind = stCmdListAccess.opKind.get( astCmd );
	switch(kind){
	case ASM_CMD_NOP :
		str = "NOP";
		break;
	case ASM_CMD_RETURN  :
		str = "RET";
		break;
	case ASM_CMD_CHOOSE :
		str = "CHOOSE";
		break;
	case ASM_CMD_CHOOSEEND :
		str = "CHOOSEEND";
		break;
	case ASM_CMD_CONFLUX  :
		str = "CONFLUX";
		break;
	case ASM_CMD_JUDGE:
		str = "JUDGE";
		break;
	case ASM_CMD_JUMP  :
		str = "JUMP";
		break;
	case ASM_CMD_BRANCH  :
		str = "BRANCH";
		break;
	case ASM_CMD_FUNCENTRY :
		str = "ENTRY";
		break;
	case ASM_CMD_FUNCEXIT   :
		str = "EXIT";
		break;
	case ASM_CMD_GETOPERAND  :
		str = "GET";
		break;
	case ASM_CMD_GETOFFSET_UNIT   :
		str = "OFFSET_U";
		break;
	case ASM_CMD_GETOFFSET    :
		str = "OFFSET";
		break;
	case ASM_CMD_GETMEMDATA   :
		str = "MEM";
		break;
	case ASM_CMD_GETADDR  :
		str = "ADDR";
		break;
	case ASM_CMD_CALL  :
		str = "CALL";
		break;
	case ASM_CMD_INC  :
		str = "INC";
		break;
	case ASM_CMD_DEC  :
		str = "DEC";
		break;
	case ASM_CMD_MINUS  :
		str = "MINUS";
		break;
	case ASM_CMD_NEGATION :
		str = "NEG";
		break;
	case ASM_CMD_BITNEGATION :
		str = "BIT_NEG";
		break;
	case ASM_CMD_CAST   :
		str = "CAST";
		break;
	case ASM_CMD_MUL   :
		str = "MUL";
		break;
	case ASM_CMD_DIV   :
		str = "DIV";
		break;
	case ASM_CMD_MOD   :
		str = "MOD";
		break;
	case ASM_CMD_ADD  :
		str = "ADD";
		break;
	case ASM_CMD_SUB  :
		str = "SUB";
		break;
	case ASM_CMD_LSFT   :
		str = "LSFT";
		break;
	case ASM_CMD_RSFT   :
		str = "RSFT";
		break;
	case ASM_CMD_GREATER   :
		str = "GREATER";
		break;
	case ASM_CMD_GREATEREQUAL   :
		str = "GREATER_EQUAL";
		break;
	case ASM_CMD_LESS   :
		str = "LESS";
		break;
	case ASM_CMD_LESSEQUAL   :
		str = "LESS_EQUAL";
		break;
	case ASM_CMD_EQUAL   :
		str = "EQUAL";
		break;
	case ASM_CMD_UNEQUAL   :
		str = "UNEQUAL";
		break;
	case ASM_CMD_BITAND   :
		str = "BIT_AND";
		break;
	case ASM_CMD_BITEXOR   :
		str = "BIT_EXOR";
		break;
	case ASM_CMD_BITINOR  :
		str = "BIT_INOR";
		break;
	case ASM_CMD_LGAND   :
		str = "LAND";
		break;
	case ASM_CMD_LGOR   :
		str = "LOR";
		break;
	case ASM_CMD_ASSIGN   :
		str = "MOV";
		break;
	case ASM_CMD_ASSIGNARG   :
		str = "ARG";
		break;
	default  :
		str = "<unknown>";
		break;
	}
	return str;
}
VOID Tr_PrintfPathInfo( AST astPath ){
	printf("PATHINFO(%ld):(%ld)%s~(%ld)%s R=%s LP(%ld) B=(%ld) BN=(%ld) N=(%ld) NN=(%ld)\n",
			astPath,
			stCmdPathInfoAccess.beginNode.get( astPath ),
			stCmdListAccess.label.get( stCmdPathInfoAccess.beginNode.get( astPath )),
			stCmdPathInfoAccess.endNode.get( astPath ),
			stCmdListAccess.label.get( stCmdPathInfoAccess.endNode.get( astPath )),
			stCmdPathInfoAccess.condition.get( astPath )==PATH_FALSE?"false":"true",
			stCmdPathInfoAccess.loopInfo.get( astPath ),
			stCmdPathInfoAccess.pathIn.get( astPath ),
			stCmdPathInfoAccess.pathIn_next.get( astPath ),
			stCmdPathInfoAccess.pathOut.get( astPath ),
			stCmdPathInfoAccess.pathOut_next.get( astPath ));
}
VOID Tr_PrintfLoopInfo( AST astPath ){
	printf("LOOPINFO(%ld):(%ld) (%ld)\n",
			astPath,
			stCmdLoopInfoAccess.begin.get( astPath ),
			stCmdLoopInfoAccess.parent.get( astPath ));
}
VOID Tr_PrintfCmdList( AST astCmd ){
	BOOL flag = FALSE;
	AST astLoop;
	printf("%-10s %ld ", Tr_DbGetCommandName(astCmd),
			astCmd );
	printf("P ");
	if( stCmdListMetaAccess.pathIn.get( astCmd )){
		printf("in%ld ", stCmdListMetaAccess.pathIn.get( astCmd ));
		flag = TRUE;
	}
	if( stCmdListMetaAccess.pathOut.get( astCmd )){
		printf("out%ld ", stCmdListMetaAccess.pathOut.get( astCmd ));
		flag = TRUE;
	}
	if( !flag ){
		printf("at%ld ", stCmdListMetaAccess.pathInfo.get( astCmd ));
	}
	printf("LP%ld", stCmdListMetaAccess.loopInfo.get( astCmd ));
	astLoop = stCmdListMetaAccess.loopInfo.get( astCmd );
	astLoop = stCmdLoopInfoAccess.parent.get( astLoop );
	while (astLoop){
		printf("->%ld", astLoop );
		astLoop = stCmdLoopInfoAccess.parent.get( astLoop );
	}
	printf(" ");
	printf("@ %s\n", Tr_DbGetLocation( LinkCommandList.getCodeScope( astCmd )));
}
static VOID tr_PrintfScopeFlg( TRVALUESCP *scp ){
	printf( "@(%s %s %s %s %d)", scp->bAddress?"addr":"value",
			scp->bBit?"bit":"byte",
			scp->bFloat?"float":"int",
			scp->bSigned?"-":"+",
			scp->size);
}
static VOID tr_PrintfValue( TRVALUE *val ){
	printf( "%s%e%s", val->ucValueFlag==0?"":"(invalid)",
			val->dbValue, val->bFloating?"F":"");
}
VOID Tr_PrintfScope( TRVALUESCP *scp ){
	TRVALUESCP type;
	if( scp == NULL ){
		printf( "{(null)}");
	}else if( scp->usScopeKind == SCOPEKIND_VOID ){
		printf( "{ no value }");
	}else if( scp->usScopeKind == SCOPEKIND_NAN ){
		printf( "{ invalid ");
		tr_PrintfScopeFlg(scp);
		printf( " }");
	}else if( scp->usScopeKind == SCOPEKIND_IN ){
		printf( "{ ");
		tr_PrintfValue( &scp->min );
		printf( "->");
		tr_PrintfValue( &scp->max );
		printf( " ");
		tr_PrintfScopeFlg(scp);
		printf( " }");
	}else{
		if( scp->bBit ){
			Tr_ScpGetMinMaxByBits( &type, scp->size, scp->bSigned );
		}else{
			Tr_ScpGetMinMaxByBytes( &type, scp->size, scp->bSigned, scp->bFloat );
		}
		printf( "{ ");
		tr_PrintfValue( &type.min );
		printf( "->");
		tr_PrintfValue( &scp->min );
		printf( " ");
		tr_PrintfValue( &scp->max );
		printf( "->");
		tr_PrintfValue( &type.max );
		printf( " ");
		tr_PrintfScopeFlg(scp);
		printf( " }");
	}

}
VOID Tr_PrintfLog( AST astCmd ){
	AST astTrVari;
	U4  flag;
	AST astLog;
	PSZ name;
	PSZ flagStr;
	TRVALUESCP scope;

	Tr_PrintfCmdList( astCmd );
	astLog = stCmdListMetaAccess.logging.get( astCmd );
	while( astLog ){
		flag = stValScpChangingLogAccess.flag.get( astLog );
		switch( flag ){
		case VARI_CHANGED_BY_ASSIGN :
			flagStr = "assign";
			astTrVari = stValScpChangingLogAccess.param.get( astLog );
			name = LinkVariable.getName( astTrVari );
			break;
		case VARI_CHANGED_BY_RELATION :
			flagStr = "condition";
			astTrVari = stValScpChangingLogAccess.param.get( astLog );
			name = LinkVariable.getName( astTrVari );
			break;
		case VARI_CHANGED_BY_MERGE :
			flagStr = "merge";
			astTrVari = stValScpChangingLogAccess.param.get( astLog );
			name = LinkVariable.getName( astTrVari );
			break;
		case VARI_CHANGED_BY_ADDR_RESTORE :
			flagStr = "addr_restore";
			astTrVari = stValScpChangingLogAccess.param.get( astLog );
			name = LinkVariable.getName( astTrVari );
			break;
		case VARI_CHANGED_BY_INLOOP_RESTORE:
			flagStr = "loop_restore";
			astTrVari = stValScpChangingLogAccess.param.get( astLog );
			name = LinkVariable.getName( astTrVari );
			break;
		case FUNCTION_CHANGED_BY_RET :
			flagStr = "return";
			astTrVari = stValScpChangingLogAccess.param.get( astLog );
			name = LinkFunction.getName( astTrVari );
			break;
		case FUNCTION_CHANGED_BY_MERGE:
			flagStr = "merge";
			astTrVari = stValScpChangingLogAccess.param.get( astLog );
			name = LinkFunction.getName( astTrVari );
			break;
		default:
			flagStr = "flag Error";
			name = "unknown";
			break;
		}
		printf("\t %lu: %s  %s ", stValScpChangingLogAccess.times.get( astLog ),
				name, flagStr );
		stValScpChangingLogAccess.getValueScope( astLog, &scope );
		Tr_PrintfScope(&scope);
		printf(" " );
		stValScpChangingLogAccess.getNegValueScope( astLog, &scope );
		Tr_PrintfScope(&scope);
		printf("\n"  );
		astLog = stValScpChangingLogAccess.next.get( astLog );
	}
}
VOID Tr_PrintfAllLog( VOID ){
	AST astMax;
	AST astCnt = MIN_ARRAY;
	printf("\n"  );
	astMax = LinkCommandList.getMax();
	while( astCnt <= astMax ){
		Tr_PrintfLog( astCnt );
		astCnt++;
	}
}
VOID Tr_PrintfBlk( AST blk ){
	AST astVari = stTrVariableBlockAccess.first.get( blk );
	PSZ name;
	TRVALUESCP scope;
	printf("BLK %5ld{\n", blk );
	while( astVari ){
		printf("              " );
		name = LinkVariable.getName( stTrVariableAccess.variable.get( astVari ) );
		printf("%s ", name );
		stTrVariableAccess.getValueScope( astVari, &scope );
		Tr_PrintfScope( &scope );
		printf(" ");
		stTrVariableAccess.getNegValueScope( astVari, &scope );
		Tr_PrintfScope( &scope );
		printf("\n");
		astVari = stTrVariableAccess.next.get( astVari );
	}
	printf("          }\n"  );
}
